﻿using System;
using System.Collections.Generic;
using System.Data.Entity.Validation;
using System.Linq;
using System.Configuration;
using MSAcademic.v2.Infrastructure.Tag.Impl;
using MSAcademic.v2.Infrastructure.User;
using Db = MSAcademic.v2.Database;

namespace MSAcademic.v2.Infrastructure.Article.Impl
{
    class ArticleCommandsImpl : IArticleCommands
    {
        public int CreateArticle(string title, int userId)
        {
            using (var database = new Db.MSAcademicDatabaseContainer())
            {
                var article = new Db.Article()
                {
                    Title = title,
                    ShortText = string.Empty,
                    LongText = string.Empty,

                    IsHidden = true,
                    IsHot = false,

                    PictueUrlNormal = ConfigurationManager.AppSettings["DefaultArticlePictureUrlNormal"],
                    PictureUrlBig = ConfigurationManager.AppSettings["DefaultArticlePictureUrlBig"],
                    PictureUrlThumbnail = ConfigurationManager.AppSettings["DefaultArticlePictureUrlThumbnail"],

                    CreatedOn = DateTimeOffset.UtcNow,

                    UserId =  userId//TODO: JURE: Povezivanje sa logiranim userom!
                };
                database.Articles.Add(article);
                database.SaveChanges();
                return article.Id;
            }
        }

        public void UpdateArticle(int id, string title, string shortText, string longText, bool isHidden, bool publish,DateTimeOffset? publishDate)
        {
            using (var database = new Db.MSAcademicDatabaseContainer())
            {
                var article = database.Articles.SingleOrDefault(x => x.Id == id);
                if (article != null)
                {
                    article.Title = title;
                    article.ShortText = shortText ?? string.Empty;
                    article.LongText = longText ?? string.Empty;
                    article.IsHidden = isHidden;
                    article.PublishedOn = publishDate;

                    if (publish)
                    {
                        article.PublishedOn = article.PublishedOn ?? DateTimeOffset.UtcNow;
                    }
                    else if (!article.PublishedOn.HasValue)
                    {
                        article.PublishedOn = null;
                    }

                    database.SaveChanges();
                }
            }
        }

        public void HideArticle(int id)
        {
            using (var database = new Db.MSAcademicDatabaseContainer())
            {
                var article = database.Articles.SingleOrDefault(x => x.Id == id);
                if (article != null)
                {
                    article.IsHidden = true;
                    database.SaveChanges();
                }
            }
        }

        public bool ToggleHideArticle(int id)
        {
            using (var database = new Db.MSAcademicDatabaseContainer())
            {
                var article = database.Articles.SingleOrDefault(x => x.Id == id);
                if (article != null)
                {
                    article.IsHidden = !article.IsHidden;
                    database.SaveChanges();
                    return article.IsHidden;
                }
                return false; //TODO: Jure: Smislit nesto bolje za ovo
            }
        }

        public void PublishArticle(int id)
        {
            using (var database = new Db.MSAcademicDatabaseContainer())
            {
                var article = database.Articles.SingleOrDefault(x => x.Id == id);
                if (article != null)
                {
                    article.PublishedOn = DateTimeOffset.UtcNow;
                    database.SaveChanges();
                }
            }
        }

        public void BindTagsToArticle(int id, List<int> tagIds)
        {
            using (var database = new Db.MSAcademicDatabaseContainer())
            {
                var article = database.Articles.SingleOrDefault(x => x.Id == id);
                if (article == null) return;
                
                //Remove unbound tags
                var tagIdsToRemove = article.Tags.Where(t => !tagIds.Contains(t.Id)).Select(t => t.Id).ToList();
                foreach (var i in tagIdsToRemove)
                {
                    article.Tags.Remove(article.Tags.Single(x => x.Id == i));
                }
                database.SaveChanges();

                //Add new tags
                var boundTagIds = article.Tags.Select(x => x.Id).ToList();
                var unboundTagIds = tagIds.Where(x => !boundTagIds.Contains(x)).ToList();
                var tags = database.Tags.Where(x => unboundTagIds.Contains(x.Id)).ToList();
                foreach (var tag in tags)
                {
                    article.Tags.Add(tag);
                }
                database.SaveChanges();
            }
        }

        public void BindSubsectionsToArticle(int id,List<int> subsectionIds )
        {
            using(var db= new Db.MSAcademicDatabaseContainer())
            {
                var article = db.Articles.SingleOrDefault(m => m.Id == id);
                if (article == null) return;
                var subsectionsToRemove =
                    article.SubSections.Where(m => !subsectionIds.Contains(m.Id)).Select(m => m.Id).ToList();
                foreach (var i in subsectionsToRemove)
                {
                    article.SubSections.Remove(article.SubSections.SingleOrDefault(m => m.Id == i));
                }
                db.SaveChanges();

                var boundSubsectionIds = article.SubSections.Select(m => m.Id).ToList();
                var unboundSubsectionIds = subsectionIds.Where(m => !boundSubsectionIds.Contains(m)).ToList();
                var subsectionsToBind = db.SubSections.Where(m => unboundSubsectionIds.Contains(m.Id)).ToList();
                foreach (var subSection in subsectionsToBind)
                {
                    article.SubSections.Add(subSection);
                }

                db.SaveChanges();
            }
        }
    }
}
